#pragma once

class TreeItem
{
public:
	TreeItem(const QVector<QVariant> &data, TreeItem *parent = 0);
	~TreeItem();

	TreeItem *child(int number);
	int childCount() const;
	int columnCount() const;
	QVariant data(int column) const;
	bool insertChildren(int position, int count, int columns);
	TreeItem *parent();
	int childNumber() const;
	bool setData(int column, const QVariant &value);

private:
	QList<TreeItem*> childItems;
	QVector<QVariant> itemData;
	TreeItem *parentItem;
};


class TreeModel : public QAbstractTableModel
{
	Q_OBJECT

public:
	const enum typeSource_t {CONTAINER, NODE, PATH, SENSOR, TEXT, NONE};
	TreeModel(QObject *parent = 0, typeSource_t _typeSource = NONE);
	~TreeModel();
	QVariant data(const QModelIndex &index, int role) const;
	QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;

	QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
	QModelIndex parent(const QModelIndex &index) const;

	int rowCount(const QModelIndex &parent = QModelIndex()) const;
	int columnCount(const QModelIndex &parent = QModelIndex()) const;

	Qt::ItemFlags flags(const QModelIndex &index) const;
	bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
	void addItem(const QString &name, const QVariant &value, const QString &units, const bool child, const int &type) const;
	int dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
private:
	typeSource_t typeSource;
	TreeItem *getItem(const QModelIndex &index) const;
	TreeItem *rootItem;
public slots:
	void dispData(QString name, int posX, int posY, int sizeW, int sizeH, bool dispTitle);
	void dispData(QString name, int posX, int posY, bool dispTitle, bool dispValue,
		double as = 0, double ad = 0, double ms = 0, double md = 0);
	void dispData(QString name, QString sourceName, QString destName, bool dispTitle, double leakagePos,
		double _additive_stochastic = 0, double _additive_deterministic = 0, 
		double _multiplicative_stochastic = 0, double _multiplicative_deterministic = 0);
	void dispData(QString name, double percentPos, bool dispTitle, bool dispValue,
		double _additive_stochastic = 0, double _additive_deterministic = 0, 
		double _multiplicative_stochastic = 0, double _multiplicative_deterministic = 0);
	void dispData(QString name, int posX, int posY);
signals:
	void ItemChanged(QString name, int posX, int posY, int sizeW, int sizeH, bool dispTitle);
	void ItemChanged(QString name, int posX, int posY, bool dispTitle, bool dispValue, 
		double as = 0, double ad = 0, double ms = 0, double md = 0);
	void ItemChanged(QString name, bool dispTitle, double leakagePos,
		double _additive_stochastic = 0, double _additive_deterministic = 0, 
		double _multiplicative_stochastic = 0, double _multiplicative_deterministic = 0);
	void ItemChanged(QString name, double percentPos, bool dispTitle, bool dispValue,
		double _additive_stochastic = 0, double _additive_deterministic = 0, 
		double _multiplicative_stochastic = 0, double _multiplicative_deterministic = 0);
	void ItemChanged(QString name, int posX, int posY);
	void update();
};

class Delegate : public QItemDelegate
{
private:
	QList<QString> unitList(QString curUnit) const;
public:
	Delegate(){}
	QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
	void setEditorData(QWidget *editor, const QModelIndex &index) const;
	void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
	void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
	QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const{return QSize(40,21);}
};
